home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
039a
/
cport1.zip
/
CPORT.DOC
< prev
next >
Wrap
Text File
|
1991-06-02
|
79KB
|
3,535 lines
Cport
C Language Serial Communications Library
Version 1.10
Copyright (c) 1991 Bri Productions
1
Table of Contents
Introduction
Acknowledgments..........................5
General Description......................5
Disclaimer...............................5
Registration.............................5
Contacting the Author....................6
A typedef................................6
"Remote Device"..........................6
Control Functions
Description..............................7
ComOpen..................................8
ComOpenS................................11
ComReopen...............................14
ComClose................................14
ComParam................................15
ComBaud.................................16
ComMode.................................17
ComHandshake............................19
ComTx...................................20
Input Functions
Description.............................22
ComGetc.................................23
ComGets.................................24
ComIn...................................25
ComFlushRx..............................26
2
ComLenRx................................27
ComPeek.................................28
Output Functions
Description.............................30
ComPutc.................................31
ComPuts.................................32
ComOut..................................33
ComFlushTx..............................34
ComLenTx................................35
Status Functions
Description.............................36
ComError................................37
ComStatus...............................38
ComRts..................................39
ComDtr..................................40
ComOut1.................................41
Data Integrity
Description.............................43
ComChecksum.............................44
ComCrc16................................45
Miscellaneous Functions
Description.............................47
ComSetBreak.............................48
ComClrBreak.............................48
ComPutScrtch............................49
ComGetScrtch............................50
3
Appendix A - Things to Look Out For.............52
Appendix B - Handshaking Schemes................53
Appendix C - The UART Chip......................55
Appendix D - The RS-232 Standard ?!!............56
Appendix E - Registration Form..................57
4
Acknowledgments.
I would like to thank Earl Jensen and Steve Hill for technical
review, Diana Hill for proofreading the documentation, Chip Curry
and Luxtron Corp for beta testing, John Kerwin for technical advice,
and Ton Kneist and Noël Gaskell for facilitating development.
General Description.
Cport is a C language interrupt-driven serial communication library
for IBM and compatible computers. Cport is compatible with most if
not all DOS based C compilers.
Some of Cport's features are:
∙ Supports COM 1 to COM 4.
∙ Baud rates from 50 to 115200 baud.
∙ Built in hardware and software handshaking.
∙ Both transmitter and receiver are interrupt-driven.
∙ Adjustable transmit and receive queues.
∙ Queues as large as 65534 bytes each.
∙ Transmit and receive queues are handled internally.
∙ Written in assembly language for optimum speed and efficiency.
DISCLAIMER.
Cport is provided AS IS. Bri Productions specifically disclaims
any and all warranties, expressed or implied, including fitness
for a particular purpose. Use this product at your own risk.
Registration.
Cport is a user supported software product. Distribution of
this product, unaltered and without charge, is encouraged. If
you find this product useful, you are encouraged to register
your copy. This allows Bri Productions to continue to provide
support low cost, high quality shareware.
The registration fee is $25.00 US dollars and includes libraries
for small, medium, compact and large memory models and complete
source code. A registration form is provided in Appendix E.
5
Contacting the author.
Bri Productions may be contacted by any of the following means:
CompuServe - 76635,2246
U.S. mail - Bri Productions
P.O.Box 7121
Fremont, CA 94537-7121
CompuServe is a trademark of CompuServe Inc.
A typedef.
You will see the data type 'byte' throughout the Cport library.
This is a typedef defined in cport.h. Byte is an unsigned
character used for byte size values.
"Remote device"
In this documentation, the expression "remote device" is used
to describe the device that the computer is communicating with.
The actual device may be a modem, serial printer or other
communications device.
6
Control Functions
Control functions manage the parameters and the modes in
which the serial port will operate. There are two functions
which are mandatory: ComOpen or ComOpenS, and ComClose.
ComOpen and/or ComOpenS open a serial port and sets the
parameters and modes. ComClose closes the opened serial port.
Failing to call ComClose prior to a program's termination will
cause the operating system crash.
ComBaud and ComMode modify one or more of the parameters/modes
of the serial port. ComParam reports on the current parameters
and handshaking under which the currently opened serial port
are operating.
ComHandshake determines if and what type of handshaking
scheme will be enabled and sets the receiver threshold. ComTx
turns the transmitter on and off, allowing you to implement
your own handshaking scheme. See Appendix B for a description
of handshaking.
7
----------------------------------------------------------------
ComOpen
----------------------------------------------------------------
Function
Opens or reopens a serial port.
Syntax
#include "cport.h"
int ComOpen(unsigned com, int baud, byte mode,
unsigned rxQ, unsigned txQ);
Parameters
com - Constant that defines the serial port to be
opened. Possibilities are:
COM1 (0xC3F8)
COM2 (0xB2F8)
COM3 (0xC3E8)
COM4 (0xB2E8)
baud - Constant defining the baud rate to which the
serial port will be initialized. Possibilities
are:
B115200 (1)
B57600 (2)
B38400 (3)
B19200 (6)
B9600 (12)
B7200 (16)
B4800 (24)
B3600 (32)
B2400 (48)
B2000 (58)
B1800 (64)
B1200 (96)
B600 (192)
B300 (384)
B150 (768)
B110 (1047)
B75 (1536)
B50 (2304)
mode - Bit ORed constant defining the word
length, number of stop bits and the
parity that the serial port will use.
Possibilities are:
8
W8 (0x03) - 8 bit words
W7 (0x02) - 7 bit words
W6 (0x01) - 6 bit words
W5 (0x00) - 5 bit words
S1 (0x00) - 1 stop bit
S2 (0x04) - 2 stop bits
NONE (0x00) - No parity
ODD (0x08) - Odd parity
EVEN (0x18) - Even parity
MARK (0x28) - Mark parity
SPACE (0x38) - Space parity
rxQ - Size, in bytes, of the receive queue.
txQ - Size in bytes, of the transmit queue.
* Limited to 32K in small and medium
memory models.
Remarks
ComOpen opens the serial port 'com' for communications.
If a serial port has been previously opened, it will
be close prior to the new serial port being opened.
The new serial port can be a different port or the
same port with new parameters. This feature allows
the programmer to reopen serial ports without first
closing the previous one.
The 4 most significant bits in 'com' represent the
interrupt vector, while the lower 12 bits represent
the port address. Constants are provided in cport.h
which will be satisfactory in most cases.
The parameter 'baud' is the baud rate divisor which
determines the baud rate. Constants are provided in
cport.h for the most common baud rates. The 'baud'
rate divisor is defined as f / (16 * baud rate) where
f is 1.8432e+6.
Achieving baud rates above 19200 is largely dependent
on many variables such as machine speed, cable length,
handshaking activity, degree bidirectional transfers,
the type UART (see Appendix C) used and activity of
other hardware interrupts.
The parameter 'mode' determines the word length,
number of stop bits and parity of the exchanged data.
Bits 0 & 1 determine the word length, bit 2
determines the number of stop bits, bit 3 enables
parity and bits 4 & 5 determine the type of parity
9
check. Constants which can be ORed together are
provided in cport.h.
'RxQ' and 'txQ' set the size of the receive and transmit
queues respectively. 'RxQ' should be at least 4 times
larger than the largest string or block of data the
programmer intends to fetch from the queue at once. '
TxQ' can be set as small as 1, but is not recommended.
In the small and medium memory models, where all data
is limited to 64K, the size queues are limited. In
the compact and large memory models, each queue can
be as large as 64K -1 (65534 bytes).
Return value
If successful, ComOpen returns 0. In the event of an
error, it returns one of the following error codes:
BAD_COM (2) - Bad 'com' parameter.
NO_UART (3) - No UART chip detected.
RCV_ALC (4) - Receive queue allocation error.
TX_ALC (5) - Transmit queue allocation error.
See also
ComOpenS ComClose ComBaud ComMode
Example
Open COM1 at 9600 baud with 8 bit words, 1 stop bit,
no parity, a 1024 byte receiver and a 512 byte
transmitter.
{
int rv;
rv = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
if(rv)
{
...error handler
}
...more code
}
10
----------------------------------------------------------------
ComOpenS
----------------------------------------------------------------
Function
Opens or reopens a serial port.
Syntax
#include "cport.h"
int ComOpenS(const C_param *param);
Parameters
param - Pointer to the structure of type 'C_param'.
The structure 'C_param' is defined as follows:
struct C_param{
unsigned com;
int baud;
byte mode;
unsigned rxQ;
unsigned txQ;
byte htype;
unsigned thresh;
};
com - Constant that defines the serial port to be
opened. Possibilities are:
COM1 (0xC3F8)
COM2 (0xB2F8)
COM3 (0xC3E8)
COM4 (0xB2E8)
baud - Constant defining the baud rate to which
the serial port will be initialized.
Possibilities are:
B115200 (1)
B57600 (2)
B38400 (3)
B19200 (6)
B9600 (12)
B7200 (16)
B4800 (24)
B3600 (32)
B2400 (48)
B2000 (58)
B1800 (64)
B1200 (96)
11
B600 (192)
B300 (384)
B150 (768)
B110 (1047)
B75 (1536)
B50 (2304)
mode - Bit ORed constant defining the word
length, number of stop bits and the
parity that the serial port will use.
Possibilities are:
W8 (0x03) - 8 bit words
W7 (0x02) - 7 bit words
W6 (0x01) - 6 bit words
W5 (0x00) - 5 bit words
S1 (0x00) - 1 stop bit
S2 (0x04) - 2 stop bits
NONE (0x00) - No parity)
ODD (0x08) - Odd parity)
EVEN (0x18) - Even parity)
MARK (0x28) - Mark parity)
SPACE (0x38) - Space parity)
rxQ - Size, in bytes, of the receive queue.
txQ - Size in bytes, of the transmit queue.
* Limited to 32K in small and medium
memory models.
htype - Type of handshaking to be used. The two types
are:
SOFT (1) - Uses XON and XOFF characters.
HARD (2) - Uses RTS and CTS.
thresh - Receive queue threshold.
Remarks
ComOpenS is an alternative to ComOpen for opening or
a reopening serial port. It takes a pointer to a
structure of parameters instead of taking discrete
arguments. It also can set the handshaking without
making a separate call to ComHandshake.
The 4 most significant bits in 'com' represent the
12
interrupt vector, while the lower 12 bits represent
the port address. Constants are provided in cport.h
which will be satisfactory in most cases.
The parameter 'baud' is the baud rate divisor which
determines the baud rate. Constants are provided in
cport.h for the most common baud rates. The 'baud'
rate divisor is defined as f / (16 * baud rate) where
f is 1.8432e+6.
Achieving baud rates above 19200 is largely dependent
on many variables such as machine speed, cable length,
handshaking activity, degree bidirectional transfers,
the type UART (see Appendix C) used and activity of
other hardware interrupts.
The parameter 'mode' determines the word length,
number of stop bits and parity of the exchanged data.
Bits 0 & 1 determine the word length, bit 2
determines the number of stop bits, bit 3 enables
parity and bits 4 & 5 determine the type of parity
check. Constants which can be ORed together are
provided in cport.h.
'RxQ' and 'txQ' set the size of the receive and transmit
queues respectively. 'RxQ' should be at least 4 times
larger than the largest string or block of data the
programmer intends to fetch from the queue at once. '
TxQ' can be set as small as 1, but is not recommended.
In the small and medium memory models, where all data
is limited to 64K, the size queues are limited. In
the compact and large memory models, each queue can
be as large as 64K -1 (65534).
The parameter 'htype' defines the type of flow
control (handshaking) to be used by the transmitter
and receiver. 'Threshold' determines when the
receiver will assert of disassert the selected
handshaking.
Return value
If successful, ComOpenS returns 0. In the event of an
error, it returns one of the following error codes:
BAD_COM (2) - Bad 'com' parameter.
NO_UART (3) - No UART chip detected.
RCV_ALC (4) - Receive queue allocation error.
TX_ALC (5) - Transmit queue allocation error.
See also
ComOpen ComParam ComHandshake ComClose
13
Example
Switch to COM2 with the same parameters.
{
struct C_param param;
ComParam(¶m);
param.com = COM2;
ComOpenS(¶m);
}
----------------------------------------------------------------
ComReopen
----------------------------------------------------------------
This function has become obsolete, however, the
function name 'ComReopen' has been retained as a
function macro to maintain backwards compatibility.
NOTE: See ComOpen and ComOpenS
----------------------------------------------------------------
ComClose
----------------------------------------------------------------
Function
Closes the currently opened serial port.
Syntax
#include "cport.h"
void ComClose(void);
Remarks
ComClose closes the currently opened serial port.
Failing to call ComClose before a program is terminated
will cause the operating system crash. It need only be
called once prior to exiting, regardless of how many
times serial ports have been reopened.
See also
ComOpen ComOpenS
14
Example
Close the serial port prior to terminating.
{
...closing code
ComClose();
exit(0)
}
----------------------------------------------------------------
ComParam
----------------------------------------------------------------
Function
Retrieves the parameters of the currently opened serial
port.
Syntax
#include "cport.h"
void ComParam(const struct C_param *param);
Remarks
ComParam retrieves the parameters and handshaking
status of the currently opened serial port and stores
them in a structure of type 'C_param'. The structure
'C_param' is defined as follows:
struct C_param{
unsigned com;
int baud;
byte mode;
unsigned rxQ;
unsigned txQ;
byte htype;
unsigned thresh;
};
See ComOpenS for a discussion of the individual
elements.
See also
ComOpen ComOpenS ComMode ComBaud
15
Example
Switch to COM2 with the same parameters.
{
struct C_param param;
ComParam(¶m);
param.com = COM2;
ComOpenS(¶m);
}
----------------------------------------------------------------
ComBaud
----------------------------------------------------------------
Function
Changes the baud rate of the currently opened serial port.
Syntax
#include "cport.h"
void ComBaud(int baud);
Parameters
baud - Constant defining the baud rate to which
the serial port will be initialized.
Possibilities are:
B115200 (1)
B57600 (2)
B38400 (3)
B19200 (6)
B9600 (12)
B7200 (16)
B4800 (24)
B3600 (32)
B2400 (48)
B2000 (58)
B1800 (64)
B1200 (96)
B600 (192)
B300 (384)
B150 (768)
B110 (1047)
B75 (1536)
B50 (2304)
16
Remarks
The parameter 'baud' is the baud rate divisor which
determines the baud rate. Constants are provided in
cport.h for the most common baud rates. The 'baud'
rate divisor is defined as f / (16 * baud rate) where
f is 1.8432e+6.
Achieving baud rates above 19200 are largely dependent
on many variables such as machine speed, cable length,
handshaking activity, degree bidirectional transfers,
the type of UART used and activity of other hardware
interrupts.
See also
ComOpen ComOpenS ComParam ComMode
Example
Set the currently opened serial port to the next baud
rate in the table 'baud'.
{
static int indx = 0;
int baud[4] = { B9600,
B2400,
B1200,
B300
};
indx++;
indx %= 4;
ComBaud(baud[indx]);
}
----------------------------------------------------------------
ComMode
----------------------------------------------------------------
Function
Changes the word length, number of stop bits and parity
of the opened serial port.
Syntax
#include "cport.h"
void ComMode(int mode);
17
Parameters
mode - Bit ORed constant defining the word length,
number of stop bits and the parity that the
serial port will use. Possibilities are:
W8 (0x03) - 8 bit words
W7 (0x02) - 7 bit words
W6 (0x01) - 6 bit words
W5 (0x00) - 5 bit words
S1 (0x00) - 1 stop bit
S2 (0x04) - 2 stop bits
NONE (0x00) - No parity)
ODD (0x08) - Odd parity)
EVEN (0x18) - Even parity)
MARK (0x28) - Mark parity)
SPACE (0x38) - Space parity)
Remarks
The parameter 'mode' determines the word length,
number of stop bits and parity of the exchanged data.
Bits 0 & 1 determine the word length, bit 2
determines the number of stop bits, bit 3 enables
parity and bits 4 & 5 determine the type of parity
check. Constants that can be ORed together are
provided in cport.h.
See also
ComOpen ComOpenS ComParam ComBaud
Example
Toggle the currently opened serial port to the next mode
in the table 'mode'.
{
static int indx = 0;
int mode[2] = { W8|S1|NONE,
W7|S1|EVEN,
};
indx ^= 1;
ComMode(mode[indx]);
}
18
----------------------------------------------------------------
ComHandshake
----------------------------------------------------------------
Function
Enables or disables flow control (handshaking).
Syntax
#include "cport.h"
void ComHandshake(byte htype, unsigned thresh);
Parameters
type - Type of handshaking to be used. The two types
are:
SOFT (1) - Uses XON and XOFF characters.
HARD (2) - Uses RTS and CTS.
thresh - Receive queue threshold.
Remarks
ComHandshake enables or disables software and/or
hardware handshaking. In software handshaking, XON
and XOFF characters are transmitted and received to
suspend and resume communications. In hardware
handshaking uses the RTS and CTS lines to suspend
and resume communications. 'Thresh' determines when
the receiver will assert and disassert.
See also
ComParam ComOpenS ComTx
Example
If COM1 is successfully opened, turn on software
handshaking and set the receiver threshold to 3/4 of
the receiver's full size.
{
int rv;
rv = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
if(rv)
{
19
...error handler
}
ComHandshake(SOFT, RCVQ_SIZE * 3 / 4);
...more code
}
----------------------------------------------------------------
ComTx
----------------------------------------------------------------
Function
Turns the transmitter on or off
Syntax
#include "cport.h"
void ComTx(byte on_off);
Parameters
on_off - Determines whether the transmitter is to be
turned on or off. Constants are provided in
cport.h. Possibilities are:
ON (1) - Turns the transmitter on
OFF (0) - Turns the transmitter off
Remarks
ComTx allows you to turn the transmitter on and off
to suspend and resume transmissions. This function
can be very useful when implementing your own
handshaking scheme.
See also
ComHandshake ComOpenS ComParam
Example
If the transmitter is off ('off') and needs to be
turned on ('turn_on'), turn it on. If the transmitter
is on and needs to be turned off, turn it off.
20
{
if(off && turn_on)
ComTx(ON);
else if(!off && turn_off)
ComTx(OFF);
}
21
Input Functions
Input fuctions interface with the receiver and the internal
receive queue.
There are four functions for fetching from the receive
queue. ComGetc and ComGets can be used to fetch control codes
as well as normal ascii characters, while ComIn is intended
for fetching binary data. ComPeek returns a copy of the head
character without removing it from the queue.
ComFlushRx flushes the receiver while ComLenRx finds
the number of characters in the queue.
22
----------------------------------------------------------------
ComGetc
----------------------------------------------------------------
Function
Fetches a character from the receive queue.
Syntax
#include "cport.h"
char ComGetc(void);
Remarks
ComGetc fetches the head character from the receive
queue. If there are no characters in the receive
queue, ComGetc returns a null character ('\0').
Return value
On Success, ComGetc returns the character from the
receive queue. If it fails it returns a '\0'.
See also
ComPutc ComGets ComIn ComPeek
Example
Get a character from the serial port and test if it
is a start of header control character.
#define SOH 1
{
char c;
c = ComGetc();
if(c == SOH)
{
...SOH code
}
else
return c;
}
23
----------------------------------------------------------------
ComGets
----------------------------------------------------------------
Function
Fetches a string of characters from the receive queue.
Syntax
#include "cport.h"
char *ComGets(char *str, int max_c, char term_c);
Parameters
*str - Pointer to the buffer where the string of
characters will be stored.
max_c - Maximum number of characters to fetch.
term_c - Termination character. ComGets will return
if this character is encountered.
Remarks
ComGets fetches a string of characters from the
receive queue. The string will be stored in 'str'.
'str' must be at least 'max_c' + 1 long to allow
for the null terminator.
ComGets will return on the first occurrence of one of
three conditions: 1) the character 'term_c' is
encountered; 2) 'max_c' characters are reached; or 3)
No more characters are available in the receive queue.
Return value
ComGets returns a pointer to the null terminated
string.
See also
ComPuts ComGetc ComIn ComLenRx
Example
Get a line of max 80 characters from the receive queue
and store it in 'str'. The string will be echoed to the
display.
24
{
char str[81];
if(ComLenRx() > 80)
puts(ComGets(str, 80, '\n'));
}
----------------------------------------------------------------
ComIn
----------------------------------------------------------------
Function
Fetches a block of bytes from the receive queue.
Syntax
#include "cport.h"
unsigned ComIn(void *abyte, unsigned num_byte);
Parameters
*abyte - Pointer to the buffer where the block of bytes
will be stored.
num_byte - Number of bytes to get from the receive queue.
Remarks
ComIn fetches a block of bytes from the receive queue
and stores it in 'abyte'. ComIn will always fetch
'num_byte' bytes unless not enough bytes are available.
ComIn is well suited for receiving binary data.
Return value
ComIn returns the number of bytes fetched.
See also
ComOut ComGetc ComGets ComLenRx
Example
Get a block of 1024 bytes from the serial port.
25
#define BLK_SZ 1024
{
byte block[BLK_SZ];
unsigned rs;
if(ComLenRx() > BLK_SZ)
{
rs = ComIn(block, BLK_SZ);
if(rs < BLK_SZ)
{
...error handler
}
}
}
----------------------------------------------------------------
ComFlushRx
----------------------------------------------------------------
Function
Flushes the receiver and receive queue.
Syntax
#include "cport.h"
void ComFlushRx(void);
Remarks
ComFlushRx flushes the receive queue and the UART of
any existing characters.
See also
ComLenRx ComFlushTx
Example
If a receive flush command is in order, flush the
receiver.
#define ...
#define RCV_FLSH 2
#define ...
{
int command;
...fetch command
26
switch(command)
{
case ...:
...case code
break;
case RCV_FLSH:
ComFlushRx();
break;
case ...:
...case code
break;
}
}
----------------------------------------------------------------
ComLenRx
----------------------------------------------------------------
Function
Calculates the number of characters in the receive queue.
Syntax
#include "cport.h"
unsigned ComLenRx(void);
Remarks
ComLenRx calculates the number of characters in the
receive queue. Valid numbers are 0 to 65534.
Return value
ComLenRx returns the number of characters presently
residing in the receive queue.
See also
ComFlushRx ComLenTx
27
Example
If there are more than 80 characters available, get a
line.
{
char str[81];
if(ComLenRx() > 80)
puts(ComGets(str, 80, '\n'));
}
----------------------------------------------------------------
ComPeek
----------------------------------------------------------------
Function
Fetches a copy of the head character in the receive
queue.
Syntax
#include "cport.h"
char ComPeek(void);
Remarks
ComPeek fetches a copy of the head character in the
receive queue. ComPeek will not remove the character
from the queue.
Return value
ComPeek returns the copy of the head character.
See also
ComGetc
Example
Determine if the head character is a control character.
#define CTRL_A 1
#define CTRL_Z 26
{
28
char peek_c;
char str[81];
peek_c = ComPeek();
if(peek_c >= CTRL_A && peek_c <= CTRL_Z)
{
switch(ComGetc())
{
...command processor
}
}
else
puts(ComGets(str, 80, '\n');
}
29
Output Functions
Output functions interface with the transmitter and the
internal transmit queue.
There are three functions for putting characters/bytes into
the transmit queue, all of which return the actual number of
characters/bytes successfully put. ComPutc and ComPuts can be
used to put control characters as well as normal ascii characters
into the transmit queue. ComOut is intended for putting binary
data into the transmit queue.
ComFlushTx flushes the transmitter while ComLenTx finds the
number of characters in the queue.
30
----------------------------------------------------------------
ComPutc
----------------------------------------------------------------
Function
Puts a character into the transmit queue.
Syntax
#include "cport.h"
int ComPutc(char c);
Parameters
c - Character to be put into the transmit queue.
Remarks
ComPutc puts a character into the transmit queue
to be transmitted. If the transmit queue is full,
the character is not put and ComPutc returns a 0.
Return value
On success, ComPutc returns a 1. If it fails, it
returns 0.
See also
ComGetc ComPuts ComOut
Example
Send an XOFF to the transmitter.
#define XOFF 13
{
if(!ComPutc(XOFF))
{
...error handler
}
31
----------------------------------------------------------------
ComPuts
----------------------------------------------------------------
Function
Puts a string of characters into the transmit queue.
Syntax
#include "cport.h"
int ComPuts(const char *str);
Parameters
*str - Pointer to the string to be put into the
transmit queue.
Remarks
ComPuts puts the string 'str' into the transmit queue
to be transmitted. If the transmit queue becomes full,
ComPuts will not attempt to put any more characters in
the queue.
Return value
ComPuts returns the actual number of characters put
into the transmit queue.
See also
ComGets ComPutc ComOut
Example
Send the string "hello world" to the transmitter.
{
char *str = "hello world";
if(ComPuts(str) < strlen(str))
{
...error handler
}
}
32
----------------------------------------------------------------
ComOut
----------------------------------------------------------------
Function
Puts a block of bytes into the transmit queue.
Syntax
#include "cport.h"
unsigned ComOut(const void *abyte, unsigned num_byte);
Parameters
*abyte - Pointer to the buffer of the block to be put
into the transmit queue.
num_byte - Number of bytes to be put into the transmit
queue.
Remarks
ComOut puts the block of bytes pointed to by 'abyte'
into the transmit queue to be transmitted.
Return value
ComOutQ returns the number of bytes actually put into
the transmit queue.
See also
ComIn ComPutc ComPuts
Example
Send a block of 128 bytes to the transmitter.
#define BLK_SZ 128
{
byte block[BLK_SZ];
if(ComOut(block, BLK_SZ) < BLK_SZ)
{
...error handler
}
33
}
}
----------------------------------------------------------------
ComFlushTx
----------------------------------------------------------------
Function
Flushes the transmit queue.
Syntax
#include "cport.h"
void ComFlushTx(void);
Remarks
ComFlushTx flushes any existing characters in the
transmit queue.
See also
ComFlushRx ComLenTx
Example
If a transmit flush command is in order, flush the
transmitter.
#define ...
#define TX_FLSH 3
#define ...
{
int command;
...fetch command
switch(command)
{
case ...:
...case code
break;
case TX_FLSH:
ComFlushTx();
break;
case ...:
34
...case code
break;
}
}
----------------------------------------------------------------
ComLenTx
----------------------------------------------------------------
Function
Calculates the number of characters in the transmit
queue.
Syntax
#include "cport.h"
unsigned ComLenTx(void);
Remarks
ComLenTx calculates the number of characters in the
receive queue. Valid numbers are 0 to 65534.
Return value
ComLenTx returns the number of characters presently
in the transmit queue.
See also
ComLenRx ComFlushTx
Example
Check if the transmitter has reached 3/4 of its
capacity.
{
if(ComLenTx() > (TX_SIZE * 3 / 4))
{
...pause
}
}
35
Status Functions
Status functions are for obtaining or setting various status.
There are two functions for obtaining status: ComError detects
line errors in the serial port; and ComStatus returns the status
of the input hardware lines.
ComDtr, ComRts and ComOut1 manipulate the output hardware
lines
36
----------------------------------------------------------------
ComError
----------------------------------------------------------------
Function
Determines if any errors have occurred since the last
call to ComError.
Syntax
#include "cport.h"
unsigned ComError(void);
Remarks
ComError determines if any errors have occurred since
the last call to ComError or since the start of the
program on the first call to ComError. ComError returns
an error word in which the bits are defined as follows:
OVERUN (0x002) - overrun error
PARITY (0x004) - parity error
FRAMING (0x008) - framing error
BREAK (0x010) - break detect
TIMOUT (0x080) - timeout
TXFULL (0x100) - transmit queue overflow
RXFULL (0x200) - receive queue overflow
Return value
If an error has occurred, ComError returns an error
word. If no errors have occurred it returns a 0.
See also
ComStatus
Example
Determine the source of the error if one has occurred.
{
unsigned com_err;
com_err = ComError();
if(com_err)
{
switch(com_err)
37
{
case OVERUN:
...over run handler
break;
case PARITY:
...parity error handler
break;
case ...
}
}
----------------------------------------------------------------
ComStatus
----------------------------------------------------------------
Function
Retrieves the status of the hardware lines.
Syntax
#include "cport.h"
byte ComStatus(void);
Remarks
ComStatus retrieves the status of the serial port's
hardware lines. ComStatus returns a status byte in
which the bits are defined as follows:
DCTS (0x01) - change in clear to send.
DDSR (0x02) - change in data set ready.
TERI (0x04) - trailing edge ring indicator.
DDCD (0x08) - change in data carrier detect.
CTS (0x10) - clear to send.
DSR (0x20) - data set ready.
RI (0x40) - ring indicator.
DCD (0x80) - data carrier detect.
Return value
ComStatus returns the status byte.
38
See also
ComError ComRts ComDtr
Example
Test if the modem is powered up and ready.
{
ComDtr(ON);
delay(40);
if(!(ComStatus() & DSR))
{
puts("modem not responding");
...what to do code
}
}
----------------------------------------------------------------
ComRts
----------------------------------------------------------------
Function
Sets or clears the Request to Send line.
Syntax
#include "cport.h"
void ComRts(byte on_off);
Parameters
on_off - Determines whether RTS is to be set or
cleared. Constants are provided in cport.h.
Possibilities are:
ON (1) - Sets RTS.
OFF (0) - Clears RTS.
Remarks
ComRts sets or clears the RTS line depending on the
value of 'on_off'. In many cases, this signal will be
looked at by the remote device to determine if it
is safe to transmit. This gives the programmer the
ability to turn off the remote device's transmitter.
39
NOTE: ComRts should never be called when hardware
handshaking is enabled.
See also
ComDtr ComOut1 ComStatus
Example
If the receiver is off ('rx_off') but ready to
receive, assert RTS. If it is on but not ready, turn
off RTS.
{
if(rx_off && rx_rdy)
ComRts(ON);
else if(!rx_off && !rx_rdy)
ComRts(OFF);
}
----------------------------------------------------------------
ComDtr
----------------------------------------------------------------
Function
Sets or clears the Data Terminal Ready line.
Syntax
#include "cport.h"
void ComDtr(byte on_off);
Parameters
on_off - Determines whether DTR is to be set or
cleared. Constants are provided in cport.h.
Possibilities are:
ON (1) - Sets DTR.
OFF (0) - Clears DTR.
Remarks
ComDtr set or clears the DTR line depending on the
40
value of 'on_off'. Setting DTR informs the remote
equipment that the computer is ready to establish
communications.
See also
ComRts ComOut1 ComStatus
Example
If an break is detected, turn off DTR.
{
unsigned com_err;
int brk_flg = 0;
com_err = ComError();
if(com_err)
{
switch(com_err)
{
case ...
case BREAK:
ComDtr(OFF);
brk_flg = 1;
break;
case ...
}
}
}
----------------------------------------------------------------
ComOut1
----------------------------------------------------------------
Function
Sets or clears the Out 1 line.
Syntax
#include "cport.h"
void ComOut1(byte on_off);
41
Parameters
on_off - Determines whether OUT1 is to be set or
cleared. Constants are provided in cport.H.
Possibilities are:
ON (1) - Sets OUT1.
OFF (0) - Clears OUT1.
Remarks
ComOut1 sets or clears the general purpose OUT1 line
depending on the value of 'on_off'. OUT1 is a general
purpose output sometimes utilized by device for a
special feature or reset.
See also
ComRts ComDtr ComStatus
Example
Reset a smart modem.
#define ComSMSet() ComOut1(ON)
#define ComSMClr() ComOut1(OFF)
{
ComSMRes();
delay(50);
ComSMClr();
}
42
Data Integrity
Two functions are currently provided for checking the integrity
of data. They are: ComChecksum and ComCrc16. ComChecksum and
ComCrc16 perform a checksum calculation and a 16 bit cyclic
redundancy check respectively, on a block of bytes. Notice also
that these functions take the same arguments as the functions
ComOut and ComIn.
43
----------------------------------------------------------------
ComChecksum
----------------------------------------------------------------
Function
Performs a checksum calculation on a block of bytes.
Syntax
#include "cport.h"
byte ComChecksum(const void *abyte, unsigned n_byte);
Parameters
*abyte - Pointer to the block on which the checksum
is to be performed
num_byte - Number of bytes in the block.
Remarks
ComChecksum performs a one byte checksum on the block
of bytes pointed to by 'abyte'. The checksum is
calculated by summing all the bytes in the block and
ignoring the carry outs.
Return value
ComChecksum returns the one byte checksum.
See also
ComCrc16 ComIn ComOut
Example
Verify the actual checksum matches the received
checksum.
{
struct Xmodem{
byte num;
byte _num;
byte data[128];
byte checksum;
}block;
44
ComIn(&block, sizeof(struct Xmodem));
if(ComChecksum(block.data, 128) != block.checksum)
{
...bad block handler
}
else...
}
----------------------------------------------------------------
ComCrc16
----------------------------------------------------------------
Function
Performs a 16 bit cyclic redundancy check on a block of
bytes.
Syntax
#include "cport.h"
unsigned ComCrc16(const void *abyte, unsigned n_byte);
Parameters
*abyte - Pointer to the block on which the 16 bit
cyclic redundancy check is to be performed.
num_byte - Number of bytes in the block.
Remarks
ComCrc16 performs a 16 bit cyclic redundancy check on
the block of bytes pointed to by 'abyte'. The 16 bit
CRC is calculated using a table of precalculated
values.
Return value
ComCrc16 returns the two byte CRC value.
See also
ComChecksum ComIn ComOut
45
Example
Verify the actual CRC matches the received CRC.
{
struct Xmodem{
byte num;
byte _num;
byte data[128];
unsigned crc16;
}block;
ComIn(&block, sizeof(struct Xmodem));
if(ComCrc16(block.data, 128) != block.crc16)
{
...bad block handler
}
else...
}
46
Misc Functions
There are two pair of misc functions: ComSetBreak and
ComClrBreak set and clear a break condition; ComPutScrtch
and ComGetScrtch write to and read from the scratch register.
47
----------------------------------------------------------------
ComSetBreak
----------------------------------------------------------------
Function
Set a break condition.
Syntax
#include "cport.h"
void ComSetBreak(void);
Remarks
ComSetBreak sets a break condition. The break condition
will stay in effect until a subsequent call to
ComClrBreak is made.
See also
ComClrBreak
Example
If the an abort condition has been declared, set a
break condition. When it clears, release the break
condition.
{
int abrt_flg;
int brk_flg;
if(abrt_flg && !brk_flg)
ComSetBreak();
else if(!abrt_flg && brk_flg)
ComClrBreak();
}
----------------------------------------------------------------
ComClrBreak
----------------------------------------------------------------
Function
Clears a previously set break condition.
48
Syntax
#include "cport.h"
void ClrBreak(void);
Remarks
ComClrBreak clears a previously set break condition.
See also
ComSetBreak
Example
If the an abort condition has been declared, set a
break condition. When it clears, release the break
condition.
{
int abrt_flg;
int brk_flg;
if(abrt_flg && !brk_flg)
ComSetBreak();
else if(!abrt_flg && brk_flg)
ComClrBreak();
}
----------------------------------------------------------------
ComPutScrtch
----------------------------------------------------------------
Function
Writes a byte to the serial port's scratch register.
Syntax
#include "cport.h"
void ComPutScrtch(byte abyte);
Parameters
abyte - The byte to be written to the scratch register.
49
Remarks
ComPutScrtch writes the byte value 'abyte' to the
UART scratch register. Not all UARTs have a scratch
register.
See also
ComGetScrtch
Example
Use the scratch register to store a status byte.
#define ComSavStatus() ComPutScrtch(ComStatus())
#define ComOldStatus() ComGetScrtch()
{
unsigned old_stat;
ComSavStatus();
...later on
old_stat = ComOldStatus();
}
----------------------------------------------------------------
ComGetScrtch
----------------------------------------------------------------
Function
Fetches the byte stored in the serial port scratch
register.
Syntax
#include "cport.h"
byte ComGetScrtch(void);
Remarks
ComGetScratch reads the byte in the UART scratch
register. Not all UARTs have a scratch register.
Return value
ComGetScrtch returns the byte read from the UART
scratch register.
50
See also
ComPutScrtch
Example
Use the scratch register to store a status byte.
#define ComSavStatus() ComPutScrtch(ComStatus())
#define ComOldStatus() ComGetScrtch()
{
unsigned old_stat;
ComSavStatus();
...later on
old_stat = ComOldStatus();
}
51
Appendix A
Things to look out for:
1) Since Cport is driven by hardware interrupts, input and
output functions will work unpredictably inside a debugger.
If a break point is set and the program is run, everything
fuctions until the break point is reached. At that point the
interrupts will probably cease and the transmitter and
receiver will freeze. Needless to say, single-stepping is out
of the question.
2) Baud rates above 19200 require special attention because they
are sensitive to many factors. Some of these factors are:
∙ Cable length
∙ Machine speed
∙ Type of UART used
∙ Activity of handshaking
∙ Degree of bidirectional transfer (transmitting and receiving
simultaneously)
∙ Other interrupt activity
The last factor, interrupt activity, includes keyboard
activity which can be a major impedance. During critical high
speed transfers, some interrupts can be temporarily masked
out (disabled) at the PIC to preclude them from impeding the
communications interrupt handler.
3) In the small and medium memory models, the near heap where
the queue buffers are allocated is limited. The data segment
(globals etc.) + the stack + allocated memory (queue buffers)
must not exceed 64K bytes. If extremely large queue(s) are
required, the compact or large model where each queue can be
as large as 65534 bytes must be used.
4) The functions ComOpen, ComOpenS and ComClose make calls to
the C functions malloc() and free().
52
Appendix B
Handshaking schemes
There are three options available for implementing handshaking.
The first two options are built-in and are enabled by calling
the function ComHandshake. The third option is external. The
three options are described as follows:
Hardware handshaking
In hardware handshaking , the hardware signals RTS and CTS
are used to achieve handshaking. RTS is used by the receiver
to signal remote device to suspend or resume transmitting.
Similarly, CTS is used by the remote device receiver to signal
the transmitter to suspend or resume transmitting.
Software handshaking
In software handshaking, the control characters XON (ctrl Q)
and XOFF (ctrl S) are used to achieve handshaking. When
either the remote device or the computer receive an XOFF
character, transmitting is suspended. When an XON character
is received transmitting is resumed.
The receiver
When software and/or hardware handshaking are enabled the
receiver monitors the length of the receive queue. If the
length exceeds the threshold set by the function
ComHandshake, the receiver will take the appropriate action
to signal the remote device to suspend transmitting. When
the length of the receive queue subsequently falls below half
of the threshold, the appropriate action is taken to signal the
remote device to resume transmitting.
The transmitter
If the computer is signaled to suspend transmitting and the
corresponding handshaking is enabled, the transmitter will
stop transmitting. Subsequently, when the computer is
signaled to resume transmitting, the transmitter will pick up
where it left off.
User handshaking
The third option for implementing handshaking is to implement
the programmer's own handshaking scheme. To accomplish this,
Cport provides the function ComTx. ComTx enables the programmer
53
to turn the transmitter on and off. When the transmitter is
turned off, transmitting halts immediately. If any characters
still reside in the transmit queue, they will remain there until
the transmitter is turned back on or the transmit queue is
flushed. More characters may be put into the transmit queue
while the transmitter is turned off.
Cooperation
In any handshaking scheme it is imperative that the computer and
the remote device recognize the handshaking scheme. For instance,
if the remote device recognizes hardware handshaking and the
computer does not, the computer will ignore any requests by the
remote device to suspend transmitting. If the remote device
recognized software handshaking and the computer did not, bogus
XON and XOFF characters might be found to be corrupting the
received data.
54
Appendix C
The UART (Universal Asynchronous Receiver/ Transmitter) chip
The UART, a single integrated circuit chip, is the backbone
of serial communications in computers today. Serial
communications in IBM and compatible computers is based on the
National Semiconductor family of UARTs. These chips include:
INS8250
INS8250-B
INS8250A
INS82C50A
NS16450
NS16C450
NS16550A
The latest and greatest is the NS16550A which features
transmitter and receiver FIFO's. This feature greatly
improves performance. Cport will take advantage of the
NS16550 chip in future versions.
55
Appendix D
The RS-232 Standard ?!!
Voltages, logic levels and pin assignments of the RS-232
standard are more or less adhered to. However, the way the
RS-232 standard prescribes data transfers to be controlled,
more commonly know as handshaking, does not work for computers.
This can lead to much confusion and frustration when trying
to connect two serial communications devices from different
manufacturers.
The book "The RS-232 Solution" by Joe Campbell addresses
this problem and includes a number of case studies. It is
recommended reading for both the novice and expert programmer.
56
Appendix E
Cport Registration Form
Name: ______________________________________________________
Company: ___________________________________________________
Address: ___________________________________________________
City: ____________________________ State: _________________
Zip Code: _________________ Phone # : _____________________
CompuServe # : _____________________________________________
How did you acquire Cport ? _________________________________
____________________________________________________________
What functions do you find most useful ?____________________
____________________________________________________________
What functions do you find least useful ?___________________
___________________________________________________________
What functions, not in Cport, would you like to see ?_______
____________________________________________________________
____________________________________________________________
Other comments ?____________________________________________
____________________________________________________________
Registration $ 25.00
California residents add sales tax ( $ 1.75 ) $________
Shipping inside continental U.S. ( $ 2.00 )
Shipping outside continental U.S. ( $ 5.00 ) $________
Total: $________
All Payments Must be in U.S. Dollars
Make check or money order payable to: Bri Productions
P.O. Box 7121
Fremont, CA 94537-7121
57